package com.atguigu.gulimall.search.thread2;

import java.util.concurrent.*;

/**
 * @author daishaobo
 * @create 2021-03-16 16:44
 */
public class ThreadTest {

    public static ExecutorService executorService = Executors.newFixedThreadPool(10);//创建一个有10个线程的固定线程池


    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main start..");
     /*   CompletableFuture.runAsync(()->{  // 这种没有返回值

            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
        }, executorService);*/
      /*  CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.supplyAsync(() -> {//可以拿到返回值
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 0;
            System.out.println("运行结果:" + i);
            return i;
        }, executorService).whenComplete((t,u)->{
            //虽然能得到异常信息但是无法修改返回数据
            System.out.println("调用成功结果是"+t+"异常时"+u);
        }).exceptionally(throwable -> {
            //可以感知异常同事返回默认值
            return 10;
        });
        Integer integer = integerCompletableFuture.get();
        System.out.println("返回值是"+integer);*/


       /* CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
            return i;
        }, executorService).handle((res, e) -> {
            if (res != null) {
                return res * 2;
            }
            if (e != null) {
                return 0;
            }
            return 0;
        }).thenApplyAsync(integer -> {

            return 111;
        });
        System.out.println("返回值是" + handle.get());*/

    /*    CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
            return i;
        }, executorService).thenRunAsync(() -> {
            System.out.println("thenRunAsync->使用新的线程执行"+"当前线程:" + Thread.currentThread().getName()+"拿不到返回值,并且无法接收到上一步执行结果");
        }, executorService).thenAcceptAsync(unused -> {
            System.out.println("thenAcceptAsync->使用新的线程执行"+"当前线程:" + Thread.currentThread().getName()+"拿不到返回值,可以接收到上一步执行结果");
        });*/

    /*    CompletableFuture<Void> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
            return i;
        }, executorService).thenAcceptAsync(unused -> {
            System.out.println("thenAcceptAsync->使用新的线程执行"+"当前线程:" + Thread.currentThread().getName()+"拿不到返回值,可以接收到上一步执行结果");
            System.out.println("执行结果"+unused);

        });*/
       /* CompletableFuture<Object> voidCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
            return i;
        }, executorService).thenApplyAsync(integer -> {
            System.out.println("thenApplyAsync->使用新的线程执行"+"当前线程:" + Thread.currentThread().getName()+"能拿到返回值,可以接收到上一步执行结果");
            return integer;
        },executorService);*/


        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2开始" + Thread.currentThread().getName());

            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务2结束");
            return 222;
        }, executorService);
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1开始" + Thread.currentThread().getName());
            System.out.println("任务1结束");

            return 111;
        }, executorService);

       /* future1.runAfterBothAsync(future2, () -> {//不能拿到被编排的两个线程的返回值

            System.out.println("任务3开始");

        }, executorService);*/

      /*  future1.thenAcceptBothAsync(future2,(t,u)->{

             System.out.println("任务3开始"+t+u);

        }, executorService);*/

       /* CompletableFuture<String> stringCompletableFuture = future1.thenCombineAsync(future2, (t, u) -> {

            System.out.println("任务3开始" + t + u);
            return "任务3开始" + t + u;

        }, executorService);*/

       /* future1.runAfterEitherAsync(future2, () -> {
            System.out.println("只要一个任务执行完毕就会执行任务3"+"不会接收返回值和返回任何值");
        },executorService);*/

       /* future1.acceptEitherAsync(future2, (integer) -> {

            System.out.println("只要一个任务执行完毕就会执行任务3"+"接收返回值但是不会返回"+integer);

        },executorService);*/

        CompletableFuture<Integer> integerCompletableFuture = CompletableFuture.allOf(future1, future2).thenApply(unused -> {

            System.out.println(unused);
            return 111;
        });
        System.out.println(integerCompletableFuture.get());

        System.out.println("main end ..");


    }


    public static void thread(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main  start...");
       /* Thread thread0 = new Thread0();
        thread0.start();
        Thread thread1 = new Thread0();
        thread1.start();*/

       /* Runnable0 runnable0 = new Runnable0();
        new Thread(runnable0).start();*/

    /*    Callable0 callable0 = new Callable0();
        FutureTask<Integer> futureTask = new FutureTask(callable0);
        new Thread(futureTask).start();
        Integer integer = futureTask.get(); //阻塞等待线程执行完毕
        System.out.println("返回的结果:"+integer);*/

       /* new Thread(()->System.out.println("线程名称:"+Thread.currentThread().getName())).start();
        new Thread(()->System.out.println("线程名称:"+Thread.currentThread().getName())).start();
        new Thread(()->System.out.println("线程名称:"+Thread.currentThread().getName())).start();
        new Thread(()->System.out.println("线程名称:"+Thread.currentThread().getName())).start();
        new Thread(()->System.out.println("线程名称:"+Thread.currentThread().getName())).start();
        new Thread(()->System.out.println("线程名称:"+Thread.currentThread().getName())).start();*/

        //上面集中创建异步任务的方法都不该使用,应该将创建线程的任务交给线程池

/*

        executorService.execute(new Thread0());
        executorService.execute(new Thread0());
        executorService.execute(new Thread0());
*/

     /*   ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
                5//核心线程数
        , 200//最大线程数
                , 10//最大存活时间
                , TimeUnit.SECONDS//时间单位
                , new LinkedBlockingQueue<>(),//超出线程数的存放队列
                Executors.defaultThreadFactory(),//创建线程的线程工厂
                new ThreadPoolExecutor.AbortPolicy());//队列满了之后的拒绝策略,基本都是抛弃,如果不想抛弃可以同步执行run方法

*/
        Executors.newCachedThreadPool();//创建一个带缓存的线程池,不过最大的线程数是integer的最大值,核心是0都可以回收
        Executors.newFixedThreadPool(10);//创建一个固定大小的线程池,核心就是最大值,都不可以进行回收
        Executors.newScheduledThreadPool(10);//定时任务的线程池
        Executors.newSingleThreadExecutor();//创建一个单线程的线程池

        System.out.println("main end ...");


    }


    public static class Thread0 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
        }
    }

    public static class Runnable0 implements Runnable {
        @Override
        public void run() {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
        }
    }

    public static class Callable0 implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            System.out.println("当前线程:" + Thread.currentThread().getName());
            int i = 10 / 2;
            System.out.println("运行结果:" + i);
            return i;
        }
    }


}
